搞运筹优化,离不开建模和求解。市面上主流的优化平台如cplex和gurobi对于各种优化问题都有极佳的表现。但缺点也十分明显,那就是贵! 早先Gurobi在同IBM cplex竞争的时候,价格十分低廉,但随着Gurobi慢慢证明了自己一哥的地位之后,定价策略也就不那么亲民了。颇有屠龙勇士变成恶龙的感觉。经费在燃烧,老板在咆哮,对于初创团队和小型项目,模型一般不大,有没有便宜又可靠的优化解决方案呢? 有的,我们自己动手丰衣足食,可以完全用开源工具高效的工作! 这就是今天要介绍的pyomo + GLPK/ipopt.
PyomoPyomo是一个基于python的开源优化建模框架。他的功能和OPL, AMPL一样,都是建模的语言。因而只负责完成建模部门,不负责求解(solve),求解是solver的职责,稍后会讲到。 Pyomo是跨平台的,不论是win/mac/linux都没问题。python 2或3也都没问题。安装也十分简便。
首次尝试,强烈建议在Anaconda环境下进行。如果没有的话,赶紧去装一个吧,Conda可以真切免除很多不必要的配置麻烦。Anaconda如何安装请戳这里
使用Anaconda环境,安装pyomo过程如下1234// 安装本体conda install -c conda-forge pyomo// 安装附加程序conda install -c conda-forge pyomo.extras
如果动手能力强,想使用pip安装,也没问题。(但pip安装可能会有各种意外的错误,初次尝试还是建议用conda)1234// 安装本体pip install pyomo// 安装Pyomo的附加程序pyomo install -extras
Solver有了模型,就要靠求解器 (solver) 来求解。大名鼎鼎的Gurobi, Cplex 和 ExpressMP都是知名的求解器。然而开源的solver选择并不多,能达到Gurobi和Cplex水平的还尚(chi1)未(ren2)出(shuo1)现(meng4)。市面上比较有人气同时pyomo也支持的有:
GLPK (Gnu Linear Programming KIt): 顾名思义,只能解线性问题。ipopt(Interior Point OPTimizer, 读作eye-pea-Opt,不是爱婆婆忒)针对非线性问题(non-linear programming)两个都能使用conda来安装,这也是为什么强烈推荐使用anaconda环境,实在是轻松加愉快。12conda install -c conda-forge glpkconda install -c conda-forge ipopt
测试让我们来测试一个简单的二次规划的模型。
$$\begin{aligned}& \text{minimize} & & x^2 + y \& & &x, y \in [-2, 2]\end{aligned}$$
下面是实现过程。12345678910111213141516171819202122232425262728293031from pyomo.environ import *# 定义模型对象modelmodel = ConcreteModel()# 定义决策变量,定义区间model.x = Var(initialize = -1.2, bounds = (-2, 2))model.y = Var(initialize = 1.0, bounds = (-2, 2))# 定义目标函数model.obj = Objective(expr = model.x**2 + model.y,sense = minimize)# 解完之后,用post process来显示x和y的数值def pyomo_postprocess(options=None, instance=None, results=None):model.x.display()model.y.display()# 主函数,模型求解if __name__ == '__main__':from pyomo.opt import SolverFactoryimport pyomo.environ# 选择ipopt作为solver。因为模型是二次,需要用非线性问题的solveropt = SolverFactory('ipopt')# 求解results = opt.solve(model)# 显示求解过程的信息results.write()print("\n Solution: \n" + '-'*60)# 调用之前定义的post process,显示决策变量最终的结果pyomo_postprocess(None, model, results)
如果pyomo和ipopt都安装正确,那么将会看到以下结果:1234567891011121314151617181920212223242526272829303132333435363738394041# ==========================================================# = Solver Results =# ==========================================================# ----------------------------------------------------------#Problem Information# ----------------------------------------------------------Problem: - Lower bound: -inf Upper bound: inf Number of objectives: 1 Number of constraints: 0 Number of variables: 2 Sense: unknown# ----------------------------------------------------------#Solver Information# ----------------------------------------------------------Solver: - Status: ok Message: Ipopt 3.12.10\x3a Optimal Solution Found Termination condition: optimal Id: 0 Error rc: 0 Time: 0.04419064521789551# ----------------------------------------------------------#Solution Information# ----------------------------------------------------------Solution: - number of solutions: 0 number of solutions displayed: 0 Solution: ------------------------------------------------------------x : Size=1, Index=NoneKey : Lower : Value: Upper : Fixed : Stale : DomainNone :-2 : -2.5183844110924177e-23 : 2 : False : False : Realsy : Size=1, Index=NoneKey : Lower : Value : Upper : Fixed : Stale : DomainNone :-2 : -2.0 : 2 : False : False : Realsobj : Size=1, Index=None, Active=TrueKey : Active : ValueNone :True : -2.0